package fafmessenger.control;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;

import fafmessenger.entity.Response;

/**
 * VOORBEELDEN:
 * 
 * Berichten ophalen:
 * ArrayList<String[]> messages = communicator.getMessages("061234400", "2010-05-16 00:00:00");
 * 
 * Registeren:
 * System.out.println(communicator.register("061279285"));
 * 
 * Bericht versturen:
 * System.out.println(communicator.sendMessage("061279285", "061234400", "Hallo, dit is een bericht van Piet!"));
 */
public class Communicator {

	private Socket socket;
	private BufferedReader inFromServer;
	private DataOutputStream outToServer;
	private final String CRLF = "\r\n";
	private final String URL = "trtruijens.nl";
	private final int PORT = 2222;
	
	public Communicator() {
		socket = null;
		inFromServer = null;
		outToServer = null;
	}
	
	public Response register(String myMobilenumber) {
		Response returnvalue = null;

		try {
			socket = new Socket(URL, PORT);
			inFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			outToServer = new DataOutputStream(socket.getOutputStream());
			
			outToServer.writeBytes("TYPE: register" + CRLF);
			outToServer.writeBytes("MOBILENUMBER: " + myMobilenumber + CRLF);
			
			outToServer.flush();

			returnvalue = parseResponse();
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (inFromServer != null) { inFromServer.close(); }
				if (outToServer != null) { outToServer.close(); }
				if (socket != null) { socket.close(); }
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return returnvalue;
	}
	
	public Object getMessages(String myMobilenumber, String fromTimestamp) {
		Object returnvalue = null;
		
		try {
			socket = new Socket(URL, PORT);
			inFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			outToServer = new DataOutputStream(socket.getOutputStream());
			
			outToServer.writeBytes("TYPE: getmessages" + CRLF);
			outToServer.writeBytes("MOBILENUMBER: " + myMobilenumber + CRLF);
			outToServer.writeBytes("TIMESTAMP: " + fromTimestamp + CRLF);
			
			outToServer.flush();
			
			Response r = parseResponse();
			
			if (r == null) {
				ArrayList<String[]> messages = new ArrayList<String[]>();
				boolean nextLineIsMessage = true;
				
				while(nextLineIsMessage) {
					String line = inFromServer.readLine();
					
					if (line.equals("END")) {
						nextLineIsMessage = false;
					} else {
						messages.add(parseMessage(line));
					}
				}
				
				returnvalue = messages;
				
			} else {
				returnvalue = r;
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (inFromServer != null) { inFromServer.close(); }
				if (outToServer != null) { outToServer.close(); }
				if (socket != null) { socket.close(); }
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return returnvalue;
	}
	
	public Response sendMessage(String fromMobilenumber, String toMobilenumber, String body) {
		Response returnvalue = new Response(410, false, "Kon geen verbinding maken met de server.");

		try {
			socket = new Socket(URL, PORT);
			inFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			outToServer = new DataOutputStream(socket.getOutputStream());
			
			outToServer.writeBytes("TYPE: sendmessage" + CRLF);
			outToServer.writeBytes("FROM: " + fromMobilenumber + CRLF);
			outToServer.writeBytes("TO: " + toMobilenumber + CRLF);
			outToServer.writeBytes("BODY: " + body + CRLF);
			
			outToServer.flush();
			
			returnvalue = parseResponse();
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (inFromServer != null) { inFromServer.close(); }
				if (outToServer != null) { outToServer.close(); }
				if (socket != null) { socket.close(); }
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return returnvalue;
	}
	
	private Response parseResponse() throws IOException {
		Response returnvalue = null;
		
		String response = inFromServer.readLine();
		String type = response.substring(response.indexOf(" ") + 1);
		
		if (type.equals("response")) {
			response = inFromServer.readLine();
			int id = Integer.parseInt(response.substring(response.indexOf(" ") + 1));
			
			response = inFromServer.readLine();
			boolean result = Boolean.parseBoolean(response.substring(response.indexOf(" ") + 1));
			
			response = inFromServer.readLine();
			String description = response.substring(response.indexOf(" ") + 1);;
			
			returnvalue = new Response(id, result, description);
		}
		
		return returnvalue;
	}
	
	private String[] parseMessage(String firstLine) throws IOException {
		String[] returnvalue = new String[4];
		
		String response = firstLine;
		String from = response.substring(response.indexOf(" ") + 1);;
		
		response = inFromServer.readLine();
		String to = response.substring(response.indexOf(" ") + 1);;
		
		response = inFromServer.readLine();
		String timestamp = response.substring(response.indexOf(" ") + 1);;
		
		response = inFromServer.readLine();
		String body = response.substring(response.indexOf(" ") + 1);;
		
		returnvalue[0] = from;
		returnvalue[1] = to;
		returnvalue[2] = timestamp;
		returnvalue[3] = body;
		
		return returnvalue;
	}
}
